package cn.zebra.dev.order.module.order.service.impl;

import cn.zebra.dev.ibatis.plus.service.impl.ServiceImpl;
import cn.zebra.dev.ibatis.plus.utils.PageUtils;
import cn.zebra.dev.ibatis.plus.utils.Query;
import cn.zebra.dev.order.module.order.constant.OrdersStatusConstant;
import cn.zebra.dev.order.module.order.dao.OrdersDao;
import cn.zebra.dev.order.module.order.entity.OrdersEntity;
import cn.zebra.dev.order.module.order.service.OrdersService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
 * @author runnable@sina.cn
 */
@Service
public class OrdersServiceImpl extends ServiceImpl<OrdersDao, OrdersEntity> implements OrdersService {

    @Override
    public OrdersEntity findByOrderNo(String orderSn) {
        QueryWrapper<OrdersEntity> wrapper = new QueryWrapper<>();
        wrapper.apply("orders_sn = {0}", orderSn);
        return getOne(wrapper);
    }

    @Override
    public OrdersEntity findByOrderIdAndUserId(Long orderId, Long memberId) {
        return selectOne("id = {0} AND orders_user_id = {1}", orderId, memberId);
    }

    @Override
    public OrdersEntity findById(Long orderId) {
        return selectOne("id = {0}", orderId);
    }

    @Override
    public Collection<OrdersEntity> findByParentId(Long parentId) {
        return selectList("parent_id = {0}", parentId);
    }

    @Override
    public Boolean updateOrderStatusByOrderSn(String orderSn, Integer status, Long point) {
        OrdersEntity entity = new OrdersEntity();
        entity.setOrdersStatus(status);
        entity.setTotalPoint(point);
        return update(entity, "order_sn = {0}", orderSn);
    }

    /**
     * 根据订单id修改订单状态
     *
     * @param id           订单id
     * @param ordersStatus 订单状态
     * @return 成功返回True 失败返回False
     */
    @Override
    public Boolean updateOrderStatusById(Long id, Integer ordersStatus) {
        OrdersEntity entity = new OrdersEntity();
        if (ordersStatus.equals(OrdersStatusConstant.PAYMENT_RECEIVED)) {
            entity.setPayTime(LocalDateTime.now());
        }
        entity.setOrdersStatus(ordersStatus);
        return update(entity, "id = {0}", id);
    }

    @Override
    public Boolean updateAddressIdByIdAndOrdersUserId(Long id, Long addressId, Long ordersUserId) {
        OrdersEntity entity = new OrdersEntity();
        entity.setAddressId(addressId);
        QueryWrapper<OrdersEntity> wrapper = new QueryWrapper<>();
        wrapper.apply("orders_user_id = {0}", ordersUserId);
        wrapper.apply("id = {0}", id);
        wrapper.apply("orders_status = {0}", OrdersStatusConstant.PENDING_PAYMENT);
        return this.update(entity, wrapper);
    }

    /**
     * 查找所有过期订单集合
     *
     * @return 过期订单集合
     */
    @Override
    public List<OrdersEntity> findExpiredOrders() {
        QueryWrapper<OrdersEntity> wrapper = new QueryWrapper<>();
        wrapper.apply("orders_status = {0}", OrdersStatusConstant.PENDING_PAYMENT);
        wrapper.apply("expired_time >= NOW()");
        return this.list(wrapper);
    }

    /**
     * 更新所有过期订单
     *
     * @return 更新成功返回True 更新失败返回False
     */
    @Override
    public Boolean updateExpiredOrders() {
        UpdateWrapper<OrdersEntity> wrapper = new UpdateWrapper<>();
        wrapper.apply("orders_status = {0}", OrdersStatusConstant.PENDING_PAYMENT);
        wrapper.apply("expired_time <= NOW()");
        OrdersEntity entity = new OrdersEntity();
        entity.setOrdersStatus(OrdersStatusConstant.EXPIRED);
        return this.update(entity, wrapper);
    }

    /**
     * 根据订单id和订单拥有者id取消订单
     *
     * @param id           订单id
     * @param ordersUserId 订单拥有者id
     * @return 取消成功返回True 取消失败返回False
     */
    @Override
    public Boolean cancel(Long id, Long ordersUserId) {
        OrdersEntity entity = new OrdersEntity();
        entity.setOrdersStatus(OrdersStatusConstant.CANCEL);
        entity.setCancelTime(LocalDateTime.now());
        UpdateWrapper<OrdersEntity> wrapper = new UpdateWrapper<>();
        wrapper.apply("id = {0}", id);
        wrapper.apply("orders_user_id = {0}", ordersUserId);
        wrapper.apply("orders_status = {0}", OrdersStatusConstant.PENDING_PAYMENT);
        return this.update(entity, wrapper);
    }

    /**
     * 查询订单分页信息
     *
     * @param params -key 查询参数
     *               productFlag    是否关联订单商品
     * @return 订单分页信息
     */
    @Override
    public PageUtils<OrdersEntity> findPage(Map<String, Object> params) {
        Page<OrdersEntity> page = new Query<OrdersEntity>(params).getPage();
        page.setRecords(baseMapper.findPage(page, params));
        return new PageUtils<>(page);
    }

    /**
     * 根据订单用户Id查找今日所有订单
     *
     * @param ordersUserId 订单用户id
     * @return 今日该用户所有订单
     */
    @Override
    public List<OrdersEntity> findNowByOrdersUserId(Long ordersUserId) {
        QueryWrapper<OrdersEntity> wrapper = new QueryWrapper<>();
        wrapper.apply("orders_user_id = {0}", ordersUserId);
        wrapper.apply("create_time = NOW()");
        return this.list(wrapper);
    }

    /**
     * 根据订单类型和订单用户Id查找今日所有订单
     *
     * @param ordersUserId 订单用户id
     * @param ordersType   订单类型
     * @return 今日该用户所有订单
     */
    @Override
    public List<OrdersEntity> findNowByOrdersUserIdAndOrdersType(Long ordersUserId, Integer ordersType) {
        QueryWrapper<OrdersEntity> wrapper = new QueryWrapper<>();
        wrapper.apply("orders_user_id = {0}", ordersUserId);
        wrapper.apply("orders_type = {0}", ordersType);
        wrapper.apply("create_time = NOW()");
        return this.list(wrapper);
    }

    /**
     * 根据订单类型和店铺(卖家)Id统计今日所有订单
     *
     * @param shopId     店铺(卖家)Id
     * @param ordersType 订单类型
     * @return 今日该用户所有订单
     */
    @Override
    public List<OrdersEntity> findNowByShopIdAndOrdersType(Long shopId, Integer ordersType) {
        QueryWrapper<OrdersEntity> wrapper = new QueryWrapper<>();
        wrapper.apply("shop_id = {0}", shopId);
        wrapper.apply("orders_type = {0}", ordersType);
        wrapper.apply("create_time = NOW()");
        return this.list(wrapper);
    }

    @Override
    public PageUtils<OrdersEntity> findPageByShopId(Map<String, Object> params) {

        QueryWrapper<OrdersEntity> wrapper = new QueryWrapper<>();
        wrapper.apply("shop_id={0}", params.get("shopId"));
        IPage<OrdersEntity> page = this.page(
                new Query<OrdersEntity>(params).getPage(),
                wrapper
        );

        return new PageUtils<>(page);
    }
}
